package com.fone.player.storage.download;

import java.io.File;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.List;

import com.fone.player.client.Request;
import com.fone.player.client.Rst;
import com.fone.player.client.XyzplaRst;
import com.fone.player.client.XyzplaRst.Cnt;
import com.fone.player.client.XyzplaRst.Frag;
import com.fone.player.client.XyzplaRst.Fraglist;
import com.fone.player.entity.OfflineCache;
import com.fone.player.entity.OfflineCacheFragment;
import com.fone.player.storage.StorageConfig;
import com.fone.player.storage.StorageModule;
import com.fone.player.util.FoneUtil;
import com.fone.player.util.L;

/**
 * 提供CacheMessageHandler工具方法
 * 
 * @author Administrator
 * 
 */
public class CacheMessageHelper {
	private static final String TAG = CacheMessageHelper.class.getSimpleName();
	private static final String FILE_PATH_EXTENTION = ".fem";
	private static final CacheMessageHelper mInstance = new CacheMessageHelper();

	public static CacheMessageHelper getInstance() {
		return mInstance;
	}

	public OfflineCache parseXYZPlayUrl(OfflineCache offlineCache) {

		String pageUrl = offlineCache.getCacheXYZPlayUrl() + "&comefrom="
				+ offlineCache.getCacheReportPage();
		StringBuffer output = new StringBuffer(pageUrl);
		if (!pageUrl.endsWith("&") && !pageUrl.endsWith("?")) {
			if (pageUrl.contains("?")) {
				output.append("&");
			} else {
				output.append("?");
			}
		}
		final String xyzPlayUrl = FoneUtil.handleUrl(pageUrl == null ? ""
				: pageUrl);
		v(TAG, "parseXYZPlayUrl", "start file=" + offlineCache.toString());
		XyzplaRst xyzplaRst = null;

		try {

			// 请求报文
			xyzplaRst = Request.getInstance().xyzplayDomain(xyzPlayUrl, "2");

		} catch (UnknownHostException e) {

			if (e != null) {

				L.w(TAG, "parseXYZPlayUrl", e.getMessage());

			}

			// ip请求,未找到主机
			xyzplaRst = Request.getInstance().xyzplayIP(xyzPlayUrl, "2");

			if (xyzplaRst == null && e != null) {

				e.printStackTrace();
				StackTraceElement[] stackTraceArray = e.getStackTrace();
				for (StackTraceElement stackTraceElement : stackTraceArray) {
					StorageModule.getInstance().writeLogStorage("E", TAG,
							"handleCacheMessage", "" + stackTraceElement);
				}
			}
		} catch (SocketTimeoutException e) {
			try {

				if (e != null) {

					L.w(TAG, "parseXYZPlayUrl", e.getMessage());

				}
				// 15秒超时重试
				xyzplaRst = Request.getInstance()
						.xyzplayDomain(xyzPlayUrl, "2");

				if (xyzplaRst == null && e != null) {

					e.printStackTrace();
					StackTraceElement[] stackTraceArray = e.getStackTrace();
					for (StackTraceElement stackTraceElement : stackTraceArray) {
						StorageModule.getInstance().writeLogStorage("E", TAG,
								"handleCacheMessage", "" + stackTraceElement);
					}
				}

			} catch (Exception exception) {

				try {

					if (e != null) {

						L.w(TAG, "parseXYZPlayUrl", e.getMessage());

					}

					// ip请求,未找到主机
					xyzplaRst = Request.getInstance()
							.xyzplayIP(xyzPlayUrl, "2");

					if (xyzplaRst == null && exception != null) {
						exception.printStackTrace();
						StackTraceElement[] stackTraceArray = e.getStackTrace();
						for (StackTraceElement stackTraceElement : stackTraceArray) {
							StorageModule.getInstance().writeLogStorage("E",
									TAG, "handleCacheMessage",
									"" + stackTraceElement);
						}
					}
				} catch (Exception e2) {
					// 不重试
					if (e2 != null) {
						e2.printStackTrace();
					}
				}

			}

		}

		if (xyzplaRst != null) {

			parseXyzplaRst(xyzplaRst, offlineCache);

		} else {
			offlineCache.setCacheDownloadState(OfflineCache.CACHE_STATE_ERROR);
			offlineCache.setCacheErrorMessage("xyzplaRst=null");
			L.e(TAG, "parseXYZPlayUrl", "end xyzplaRst=null");
		}

		L.v(TAG, "parseXYZPlayUrl", "end file=" + offlineCache.toString());

		return offlineCache;
	}

	/**
	 * 
	 * 报文解析器
	 * 
	 * @author wangyang
	 * @since 2014年6月1日
	 */
	private void parseXyzplaRst(XyzplaRst t, OfflineCache offlineCache) {

		int result = t != null ? t.result : -1;
		v(TAG, "parseXyzplaRst", "result=" + result);
		if (result == 0) {
			Cnt cnt = t != null ? t.cnt : null;
			// 名称
			String name = cnt != null ? cnt.name : "";
			offlineCache.setCacheName(name);
			Fraglist fraglistTag = cnt != null ? cnt.fraglist : null;
			// 总时长
			long duration = fraglistTag != null ? fraglistTag.t : 0;
			offlineCache.setCacheDuration(duration);
			List<Frag> fragList = fraglistTag != null ? fraglistTag.fragList
					: null;
			if (fragList == null || fragList.size() == 0) {
				e(TAG, "parseXyzplaRst", "fragList is empty");
				// 记录error信息
				offlineCache
						.setCacheDownloadState(OfflineCache.CACHE_STATE_ERROR);
				offlineCache
						.setCacheErrorCode(OfflineCache.CACHE_ERROR_CODE_FRAGMENT_URL_NULL);
				offlineCache.setCacheErrorMessage("解析成功,但未解析到分片地址");
				return;
			}
			v(TAG, "parseXyzplaRst", "fragList.size=" + fragList.size());

			// 清空数据
			offlineCache.clearOfflineCacheFragmentList();

			for (int i = 0; i < fragList.size(); i++) {

				Frag frag = fragList.get(i);

				OfflineCacheFragment offlineCacheFragment = new OfflineCacheFragment();
				offlineCacheFragment.setCacheCID(offlineCache.getCacheCID());
				// 获得存储路径
				String storagePath = getOfflineCacheFragmentStoragePath(
						offlineCache, i);
				offlineCacheFragment
						.setCacheFragmentStoragePath(storagePath);

				String downloadUrl = frag != null ? frag.url : "";
				offlineCacheFragment.setCacheFragmentUrl(downloadUrl);
				long unitIndexTime = frag != null ? frag.t : 0;
				offlineCacheFragment.setCacheDuration(unitIndexTime);
				if (fragList.size() > 1
						&& offlineCacheFragment.getCacheDuration() == 0) {
					e(TAG,
							"parseXyzplaRst",
							"fragError name="
									+ name
									+ " fragTime="
									+ offlineCacheFragment.getCacheDuration()
									+ " fragUrl="
									+ offlineCacheFragment
											.getCacheFragmentUrl()
									+ " xyzPlayUrl="
									+ offlineCache.getCacheXYZPlayUrl());
				}
				v(TAG, "parseXyzplaRst", "name=" + name + " fragTime="
						+ offlineCacheFragment.getCacheDuration() + " fragUrl="
						+ offlineCacheFragment.getCacheFragmentUrl());
				offlineCache.addOfflineCacheFragment(offlineCacheFragment);
			}

		} else {
			Rst.Error error = t != null ? t.error : null;
			String errorCode = error != null ? error.errorcode : "";
			String errorMsg = error != null ? error.errormsg : "";
			e(TAG, "parseXyzplaRst", "errorCode=" + errorCode + " errorMsg="
					+ errorMsg);
			// 记录error信息
			offlineCache.setCacheDownloadState(OfflineCache.CACHE_STATE_ERROR);
			offlineCache
					.setCacheErrorCode(OfflineCache.CACHE_ERROR_CODE_MESSAGE_PARSE_FAIL);
			offlineCache.setCacheErrorMessage("errorCode=" + errorCode
					+ " errorMsg=" + errorMsg);
		}

	}

	/**
	 * 
	 * 根据参数获取分片存储路径(root+视频来源名称+ccid_cid+fragmentIndex.fem)
	 * 
	 * @param offlineCachePath
	 * @param offlineCache
	 * @param fragmentIndex
	 * @return String
	 */
	private String getOfflineCacheFragmentStoragePath(
			OfflineCache offlineCache, int fragmentIndex) {
		String filePath = offlineCache.getCacheStoragePath();
		StringBuilder storagePath = new StringBuilder();
		storagePath.append(filePath);
		storagePath.append(File.separator);
		storagePath.append(fragmentIndex + 1);
		storagePath.append(FILE_PATH_EXTENTION);
		File file = new File(storagePath.toString());

		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				if (e != null) {
					e.printStackTrace();
				}

			}
		}
		return storagePath.toString();
	}

	/**
	 * 
	 * 根据参数获取视频存储路径(root+视频来源名称+ccid_cid)
	 * 
	 * @param offlineCachePath
	 * @param offlineCache
	 * @param fragmentIndex
	 * @return String
	 */
	public String getOfflineCacheFileStoragePath(String offlineCachePath,
			OfflineCache offlineCache) {
		StringBuilder storagePath = new StringBuilder();
		storagePath.append(offlineCachePath);
		storagePath.append(File.separator);
		String sourceName = offlineCache.getCacheSourceName();
		if (sourceName != null && !"".equals(sourceName)) {
			storagePath.append(sourceName);
		} else {
			storagePath.append("未知");
		}
		storagePath.append(File.separator);
		storagePath.append(offlineCache.getCacheCCID());
		storagePath.append("_");
		storagePath.append(offlineCache.getCacheCID());
		storagePath.append(File.separator);
		storagePath.append(offlineCache.getCacheDefinitionType());
		File file = new File(storagePath.toString());
		if (!file.exists()) {
			file.mkdirs();
		}
		return storagePath.toString();
	}

	static void v(String tag, String type, String msg) {
		if (StorageConfig.CACHE_MESSAGE_HANDLER_LOG) {
			L.v(tag, type, msg);
		}
	}

	static void e(String tag, String type, String msg) {
		if (StorageConfig.CACHE_MESSAGE_HANDLER_LOG) {
			L.e(tag, type, msg);
		}
	}
}
